package uk.co.agileworks.bidpirate.bidding;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import uk.co.agileworks.bidpirate.model.Bid;
import uk.co.agileworks.bidpirate.service.BusinessLogic;

@Service
public final class BidTimer {

	class BidTimerTask extends TimerTask {
		@Override
		public void run() {
			LOGGER.trace("BidTimerTask");
			for (Bid bid : businessLogic.getBidding()) {
				bidExecutor.execute(newBidTask(bid));
			}
		}
	}

	private static final Logger LOGGER = LoggerFactory.getLogger(BidTimer.class);
	private static final long TO_MILLISECONDS = 1000;

	@Autowired
	private ApplicationContext ctx;

	@Autowired
	private BusinessLogic businessLogic;

	private Executor bidExecutor = Executors.newCachedThreadPool();
	private Timer timer = new Timer("bidTimer");

	@Autowired
	@Qualifier("bidTimerDelaySeconds")
	private Integer delaySeconds;

	@Autowired
	@Qualifier("bidTimerPeriodSeconds")
	private Integer periodSeconds;

	public BidTimer() {
	}

	public BidTimer(int delaySeconds, int periodSeconds) {
		this.delaySeconds = delaySeconds;
		this.periodSeconds = periodSeconds;
	}

	Runnable newBidTask(Bid bid) {
		return (Runnable) ctx.getBean("bidTask", bid);
	}

	@PostConstruct
	void start() {
		timer.schedule(new BidTimerTask(), delaySeconds * TO_MILLISECONDS, periodSeconds
				* TO_MILLISECONDS);
	}

	@PreDestroy
	void stop() {
		timer.cancel();
	}

}
